importScripts("../src/webrpc.js");

new webrpc.Service("shootingService", {
    MAX_X : 200,
    MAX_Y : 250,
    MIN_X : 0,
    MIN_Y : 0,
    SHOT_COUNT : 20,
    ENEMY_COUNT : 10,
    ENEMY_SIDE_SPACE : 20,
    KEY_CODE : { "right" : 39, "left" : 37, "up" : 38, "down" : 40, "shot" : 32 },
    isRight : false,
    isLeft : false,
    isUp : false,
    isDown : false,
    isShot : false,
    myFighter : {
        x : 100,
        y : 230,
        isActive : true
    },
    enemies : null,
    enemy : function(i, x) {
        this.id = i;
        this.x = x;
        this.y = -20;
        this.isActive = true;
        this.plusMinus = 1;
        this.turnCount = 0;
    },
    shots : null,
    shot : function(i) {
        this.id = i;
        this.x = -20;
        this.y = -20;
        this.isActive = false;
        this.waitCount = 0;
    },
    alert : function(msg) {
        // for debug
        webrpc.parent.outputService.alert(msg);
    },
    setKeyDown : function(keyCode) {
        switch (keyCode) {
            case this.KEY_CODE["right"]:
                this.isRight = true;
                break;
            case this.KEY_CODE["left"]:
                this.isLeft = true;
                break;
            case this.KEY_CODE["up"]:
                this.isUp = true;
                break;
            case this.KEY_CODE["down"]:
                this.isDown = true;
                break;
            case this.KEY_CODE["shot"]:
                this.isShot = true;
                break;
        }
    },
    setKeyUp : function(keyCode) {
        switch (keyCode) {
            case this.KEY_CODE["right"]:
                this.isRight = false;
                break;
            case this.KEY_CODE["left"]:
                this.isLeft = false;
                break;
            case this.KEY_CODE["up"]:
                this.isUp = false;
                break;
            case this.KEY_CODE["down"]:
                this.isDown = false;
                break;
            case this.KEY_CODE["shot"]:
                this.isShot = false;
                break;
        }
    },
    main : function() {
        this.createEnemyObject();
        this.createShotObject();
        this.setMyFighterCoordinates();
        this.setEnemyCoordinates();
        this.setShotCoordinates();
    },
    createEnemyObject : function() {
        if (this.enemies == null) {
            var arrayId = new Array(this.ENEMY_COUNT);
            this.enemies = new Array(this.ENEMY_COUNT);
            for (i = 0; i < this.enemies.length; i++) {
                var x = Math.floor(Math.random() * (this.MAX_X - (this.ENEMY_SIDE_SPACE * 2))) + this.ENEMY_SIDE_SPACE;
                this.enemies[i] = new this.enemy(i, x);
                arrayId[i] = i;
            }
            webrpc.parent.outputService.createEnemy(arrayId);
        }
    },
    createShotObject : function() {
        // create shot object
        if (this.shots == null) {
            var arrayId = new Array(this.SHOT_COUNT);
            this.shots = new Array(this.SHOT_COUNT);
            for (i = 0; i < this.shots.length; i++) {
                this.shots[i] = new this.shot(i);
                arrayId[i] = i;
            }
            webrpc.parent.outputService.createShot(arrayId);
        }
    },
    setMyFighterCoordinates : function() {
        var self = this;
        exec();
        
        /**
         * execute setting my fighter coordinates
         */
        function exec() {
            // judgement hitting between enemy and my fighter
            if (self.enemies != null) {
                for (i = 0; i < self.enemies.length; i++) {
                    if (self.enemies[i].isActive) {
                        if (self.JudgeHit(self.enemies[i].x, self.enemies[i].y, self.myFighter.x, self.myFighter.y, 15)) {
                            self.myFighter.isActive = false;
                            webrpc.parent.outputService.explode();
                        }
                    }
                }
            }
            // my fighter coordinates
            if (self.myFighter.isActive) {
                if (self.isRight) { self.myFighter.x += 5; }
                if (self.isLeft) { self.myFighter.x -= 5; }
                if (self.isUp) { self.myFighter.y -= 5; }
                if (self.isDown) { self.myFighter.y += 5; }
                if (self.myFighter.x > self.MAX_X) { self.myFighter.x = self.MAX_X; }
                if (self.myFighter.y > self.MAX_Y) { self.myFighter.y = self.MAX_Y; }
                if (self.myFighter.x < self.MIN_X) { self.myFighter.x = self.MIN_X; }
                if (self.myFighter.y < self.MIN_Y) { self.myFighter.y = self.MIN_Y; }
                webrpc.parent.outputService.setMyFighterCoordinates(self.myFighter.x, self.myFighter.y);
                setTimeout(function() { exec(); }, 50);
            }
        }
    },
    setEnemyCoordinates : function() {
        var self = this;
        exec();
        
        /**
         * execute setting enemy coordinates
         */
        function exec() {
            // judgement hitting between enemy and shot
            if (self.enemies != null && self.shots != null) {
                for (i = 0; i < self.enemies.length; i++) {
                    if (self.enemies[i].isActive) {
                        for (j = 0; j < self.shots.length; j++) {
                            if (self.shots[j].isActive) {
                                if (self.JudgeHit(self.enemies[i].x, self.enemies[i].y, self.shots[j].x, self.shots[j].y, 15)) {
                                    self.enemies[i].isActive = false;
                                    webrpc.parent.outputService.addScore(10);
                                }
                            }
                        }
                    }
                }
            }
            // enemy coordinates
            var isRestart = true;
            for (i = 0; i < self.enemies.length; i++) {
                if (self.enemies[i].isActive) {
                    isRestart = false;
                    var x = 5;
                    var y = 5;
                    // move pattern
                    switch (self.enemies[i].id) {
                        case 0:
                            x = 7;
                            y = 2;
                            break;
                        case 1:
                            x = 2;
                            y = 4;
                            break;
                        case 2:
                            x = 3;
                            y = 3;
                            break;
                        case 3:
                            x = 1;
                            y = 5;
                            break;
                        case 4:
                            x = 1;
                            y = 3;
                            break;
                        case 5:
                            x = 6;
                            y = 2;
                            break;
                        case 6:
                            x = 5;
                            y = 3;
                            break;
                        case 7:
                            x = 5;
                            y = 2;
                            break;
                        case 8:
                            x = 5;
                            y = 5;
                            break;
                        default:
                            x = 5;
                            y = 5;
                            break;
                    }
                    
                    self.enemies[i].x += (x * self.enemies[i].plusMinus);
                    
                    if (self.enemies[i].x > self.MAX_X) {
                        self.enemies[i].x = self.MAX_X;
                        self.enemies[i].turnCount += 1;
                        if (self.enemies[i].turnCount > 5) {
                            self.enemies[i].turnCount = 0;
                            self.enemies[i].plusMinus = -1;
                        }
                    } else if (self.enemies[i].x < 0) {
                        self.enemies[i].x = 0;
                        self.enemies[i].turnCount += 1;
                        if (self.enemies[i].turnCount > 5) {
                            self.enemies[i].turnCount = 0;
                            self.enemies[i].plusMinus = 1;
                        }
                    }
                    
                    self.enemies[i].y += y;
                    
                    if (self.enemies[i].y > self.MAX_Y) {
                        self.enemies[i].y = self.MAX_Y;
                        self.enemies[i].isActive = false;
                    }
                } else {
                    self.enemies[i].y = -20;
                }
                webrpc.parent.outputService.setEnemyCoordinates(self.enemies[i].id, self.enemies[i].x, self.enemies[i].y);
            }
            if (isRestart) {
                for (i = 0; i < self.ENEMY_COUNT; i++) {
                    var x = Math.floor(Math.random() * (self.MAX_X - (self.ENEMY_SIDE_SPACE * 2))) + self.ENEMY_SIDE_SPACE;
                    self.enemies[i].x = x;
                    self.enemies[i].isActive = true;
                }
            }
            setTimeout(function() { exec(); }, 50);
        }
    },
    setShotCoordinates : function() {
        var self = this;
        exec();
        
        /**
         * execute setting shot coordinates
         */
        function exec() {
            if (self.isShot && self.myFighter.isActive) {
                for (i = 0; i < self.shots.length; i++) {
                    if (self.shots[i].isActive == false) {
                        if (self.shots[i].waitCount < 2) {
                            self.shots[i].waitCount += 1;
                        } else {
                            self.shots[i].x = self.myFighter.x;
                            self.shots[i].y = self.myFighter.y;
                            self.shots[i].isActive = true;
                            self.shots[i].waitCount = 0;
                        }
                        break;
                    }
                }
            }
            
            for (i = 0; i < self.shots.length; i++) {
                if (self.shots[i].isActive) {
                    if (self.shots[i].y < 0) {
                        self.shots[i].y = 0;
                        self.shots[i].isActive = false;
                    } else {
                        self.shots[i].y -= 8;
                    }
                } else {
                    self.shots[i].x = -20;
                    self.shots[i].y = -20;
                }
                webrpc.parent.outputService.setShotCoordinates(i, self.shots[i].x, self.shots[i].y);
            }
            setTimeout(function() { exec(); }, 50);
        }
    },
    JudgeHit : function(enemy_x, enemy_y, target_x, target_y, CollisionDistance) {
        var isHit = false;
        var x, y, z;
        x = (enemy_x - target_x) * (enemy_x - target_x);
        y = (enemy_y - target_y) * (enemy_y - target_y);
        z = CollisionDistance * CollisionDistance;
        if ((x + y) < z) {
            isHit = true;
        }
        return isHit;
    }
});
